home *** CD-ROM | disk | FTP | other *** search
- //------------------------------------------------------------------------
- // ^FILE: unix.c - implement the unix-specific portions of CmdLine
- //
- // ^DESCRIPTION:
- // This file implements the public and private CmdLine library functions
- // that are specific to the native command-line syntax of Unix.
- //
- // The following functions are implemented:
- //
- // CmdLine::parse_option() -- parse an option
- // CmdLine::parse_keyword() -- parse a keyword
- // CmdLine::parse_value() -- parse a value
- // CmdLine::parse_arg() -- parse a single argument
- // CmdLine::arg_error() -- format an argument for error messages
- // CmdLine::fmt_arg() -- format an argument for usage messages
- //
- // ^HISTORY:
- // 01/09/92 Brad Appleton <brad@ssd.csd.harris.com> Created
- //
- // 03/01/93 Brad Appleton <brad@ssd.csd.harris.com>
- // - Added ALLOW_PLUS to list of CmdLine configuration flags
- //-^^---------------------------------------------------------------------
-
- #include <iostream.h>
- #include <strstream.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "exits.h"
- #include "cmdline.h"
- #include "states.h"
-
- //
- // Some Helper function for getting and recognizing prefixes
- //
-
- // Function to tell us if an argument looks like an option
- inline static int
- isOPTION(const char * s) {
- return ((*(s) == '-') && ((*((s)+1) != '-')) && ((*((s)+1) != '\0'))) ;
- }
-
- // Function to return the option-prefix
- inline static const char *
- OptionPrefix(void) { return "-" ; }
-
-
- // Function to tell us if an argument looks like a long-option.
- //
- // NOTE: allowing "+" does not preclude the use of "--"
- //
- inline static int
- isKEYWORD(const char *s, int allow_plus) {
- return (((*(s) == '-') && (*((s)+1) == '-') && (*((s)+2) != '\0')) ||
- (allow_plus && (*(s) == '+') && ((*((s)+1) != '\0')))) ;
- }
-
- // Function to return the long-option prefix
- inline static const char *
- KeywordPrefix(int allow_plus) { return (allow_plus) ? "+" : "--" ; }
-
- // Need to know when an argument means "end-of-options"
- inline static int
- isENDOPTIONS(const char *s) {
- return ((*(s) == '-') && (*((s)+1) == '-') && (*((s)+2) == '\0')) ;
- }
-
- // Function to return the "end-of-options" string
- inline static const char *
- EndOptions(void) { return "--" ; }
-
-
- //-------
- // ^FUNCTION: CmdLine::parse_option - parse a Unix option
- //
- // ^SYNOPSIS:
- // unsigned CmdLine::parse_option(arg);
- //
- // ^PARAMETERS:
- // const char * arg;
- // -- the command-line argument containing the prospective option
- //
- // ^DESCRIPTION:
- // This routine will attempt to "handle" all options specified in
- // the string "arg". For each option found, its compile-function
- // is called and the corresponding state of both the command
- // and of the matched option(s) is (are) updated.
- //
- // ^REQUIREMENTS:
- // "arg" should point past any leading option prefix (such as "-").
- //
- // ^SIDE-EFFECTS:
- // "cmd" is modified accordingly as each option is parsed (as are its
- // constituent arguments). If there are syntax errors then error messages
- // are printed if QUIET is NOT set.
- //
- // ^RETURN-VALUE:
- // NO_ERROR is returned if no errors were encountered. Otherwise the
- // return value is a combination of bitmasks of type CmdLine::CmdStatus
- // (defined in <cmdline.h>) indicating all the problems that occurred.
- //
- // ^ALGORITHM:
- // see if we left an option dangling without parsing its value.
- // for each option bundled in "arg"
- // try to match the option
- // if no match issue a message (unless QUIET is set)
- // else
- // if the option takes NO argument than handle that
- // else if the option takes an argument
- // if the rest or arg is not empty then
- // call the option's compile-function using the rest of
- // arg as the value.
- // skip past whatever portion of value was used
- // else
- // update the state of the command to show that we are expecting
- // to see the value for this option as the next argument.
- // endif
- // endif
- // update the state of the argument.
- // endif
- // endfor
- //-^^----
- unsigned
- CmdLine::parse_option(const char * arg)
- {
- const char * save_arg = arg;
- unsigned save_flags = 0, rc = 0 ;
- CmdArg * cmdarg = NULL;
- int bad_val;
-
- // see if we left an argument dangling without a value
- ck_need_val() ;
-
- do { // loop over bundled options
- cmdarg = opt_match(*arg);
- if (cmdarg == NULL) {
- // If we were in the middle of a guess - sorry no cigar, otherwise
- // guess that maybe this is a keyword and not an keyword.
- //
- if (cmd_state & cmd_GUESSING) {
- if (arg == save_arg) return BAD_OPTION;
- } else {
- if (! (cmd_flags & NO_GUESSING)) {
- cmd_state |= cmd_GUESSING;
- rc = parse_keyword(arg);
- cmd_state &= ~cmd_GUESSING;
- if (rc != BAD_KEYWORD) return rc;
- }
- }
- if (! (cmd_flags & QUIET)) {
- error() << "unknown option \"" << OptionPrefix() << char(*arg)
- << "\"." << endl ;
- }
- rc |= BAD_OPTION ;
- ++arg ; // skip bad option
- continue ;
- }
- ++arg ; // skip past option character
- save_flags = cmdarg->flags() ;
- cmdarg->clear();
- cmdarg->set(CmdArg::OPTION) ;
- if ((! *arg) && (cmdarg->syntax() & CmdArg::isVALTAKEN)) {
- // End of string -- value must be in next arg
- // Save this cmdarg-pointer for later and set the parse_state to
- // indicate that we are expecting a value.
- //
-
- if (cmdarg->syntax() & CmdArg::isVALSTICKY) {
- // If this argument is sticky we already missed our chance
- // at seeing a value.
- //
- if (cmdarg->syntax() & CmdArg::isVALREQ) {
- if (! (cmd_flags & QUIET)) {
- error() << "value required in same argument for "
- << OptionPrefix() << char(cmdarg->char_name())
- << " option." << endl;
- }
- rc |= (VAL_MISSING | VAL_NOTSTICKY) ;
- cmdarg->flags(save_flags);
- } else {
- // The value is optional - set the GIVEN flag and call
- // handle_arg with NULL (and check the result).
- //
- const char * null_str = NULL;
- cmdarg->set(CmdArg::GIVEN) ;
- cmd_parse_state = cmd_START_STATE ;
- bad_val = handle_arg(cmdarg, null_str);
- if (bad_val) {
- if (! (cmd_flags & QUIET)) {
- arg_error("bad value for", cmdarg) << "." << endl ;
- }
- rc |= BAD_VALUE ;
- cmdarg->flags(save_flags);
- }
- }
- } else {
- // Wait for the value to show up next time around
- cmdarg->set(CmdArg::GIVEN) ;
- cmd_matched_arg = cmdarg ;
- cmd_parse_state = cmd_WANT_VAL ;
- if (cmdarg->syntax() & CmdArg::isVALREQ) {
- cmd_parse_state += cmd_TOK_REQUIRED ;
- }
- }
- return rc ;
- }
-
- // If this option is an isVALSEP and "arg" is not-empty then we
- // have an error.
- //
- if ((cmdarg->syntax() & CmdArg::isVALTAKEN) &&
- (cmdarg->syntax() & CmdArg::isVALSEP)) {
- if (! (cmd_flags & QUIET)) {
- error() << "value required in separate argument for "
- << OptionPrefix() << char(cmdarg->char_name())
- << " option." << endl;
- }
- rc |= (VAL_MISSING | VAL_NOTSEP) ;
- cmdarg->flags(save_flags);
- return rc;
- } else {
- // handle the option
- const char * save_arg = arg;
- bad_val = handle_arg(cmdarg, arg);
- if (bad_val) {
- if (! (cmd_flags & QUIET)) {
- arg_error("bad value for", cmdarg) << "." << endl ;
- }
- rc |= BAD_VALUE ;
- cmdarg->flags(save_flags);
- }
- cmdarg->set(CmdArg::GIVEN);
- if (arg != save_arg) cmdarg->set(CmdArg::VALGIVEN);
- }
- } while (arg && *arg) ;
-
- return rc ;
- }
-
-
- //-------
- // ^FUNCTION: CmdLine::parse_keyword - parse a Unix keyword
- //
- // ^SYNOPSIS:
- // unsigned CmdLine::parse_keyword(arg);
- //
- // ^PARAMETERS:
- // const char * arg;
- // -- the command-line argument containing the prospective keyword
- //
- // ^DESCRIPTION:
- // This routine will attempt to "handle" the keyword specified in
- // the string "arg". For any keyword found, its compile-function
- // is called and the corresponding state of both the command
- // and of the matched keyword(s) is (are) updated.
- //
- // ^REQUIREMENTS:
- // "arg" should point past any leading keyword prefix (such as "--").
- //
- // ^SIDE-EFFECTS:
- // "cmd" is modified accordingly as the keyword is parsed (as are its
- // constituent arguments). If there are syntax errors then error messages
- // are printed if QUIET is NOT set.
- //
- // ^RETURN-VALUE:
- // NO_ERROR is returned if no errors were encountered. Otherwise the
- // return value is a combination of bitmasks of type CmdLine::CmdStatus
- // (defined in <cmdline.h>) indicating all the problems that occurred.
- //
- // ^ALGORITHM:
- // see if we left an option dangling without parsing its value.
- // look for a possible value for this keyword denoted by ':' or '='
- // try to match "arg" as a keyword
- // if no match issue a message (unless QUIET is set)
- // else
- // if the keyword takes NO argument than handle that
- // else if the keyword takes an argument
- // if a value was found "arg"
- // call the keyword's compile-function with the value found.
- // else
- // update the state of the command to show that we are expecting
- // to see the value for this option as the next argument.
- // endif
- // endif
- // update the state of the argument.
- // endif
- //-^^----
- unsigned
- CmdLine::parse_keyword(const char * arg)
- {
- unsigned save_flags = 0, rc = 0 ;
- CmdArg * cmdarg = NULL ;
- int ambiguous = 0, len = -1, bad_val;
- const char * val = NULL ;
-
- int plus = (cmd_flags & ALLOW_PLUS) ; // Can we use "+"?
-
- // see if we left an argument dangling without a value
- ck_need_val() ;
-
- // If there is a value with this argument, get it now!
- val = ::strpbrk(arg, ":=") ;
- if (val) {
- len = val - arg ;
- ++val ;
- }
-
- cmdarg = kwd_match(arg, len, ambiguous);
- if (cmdarg == NULL) {
- // If we were in the middle of a guess - sorry no cigar, otherwise
- // guess that maybe this is an option and not a keyword.
- //
- if (cmd_state & cmd_GUESSING) {
- return BAD_KEYWORD;
- } else if ((! ambiguous) || (len == 1)) {
- if (! (cmd_flags & NO_GUESSING)) {
- cmd_state |= cmd_GUESSING;
- rc = parse_option(arg);
- cmd_state &= ~cmd_GUESSING;
- if (rc != BAD_OPTION) return rc;
- }
- }
- if (! (cmd_flags & QUIET)) {
- error() << ((ambiguous) ? "ambiguous" : "unknown") << " option "
- << "\"" << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
- : KeywordPrefix(plus))
- << arg << "\"." << endl ;
- }
- rc |= ((ambiguous) ? KWD_AMBIGUOUS : BAD_KEYWORD) ;
- return rc ;
- }
-
- save_flags = cmdarg->flags() ;
- cmdarg->clear();
- cmdarg->set(CmdArg::KEYWORD) ;
- if ((cmdarg->syntax() & CmdArg::isVALTAKEN) && (val == NULL)) {
- // Value must be in the next argument.
- // Save this cmdarg for later and indicate that we are
- // expecting a value.
- //
- if (cmdarg->syntax() & CmdArg::isVALSTICKY) {
- // If this argument is sticky we already missed our chance
- // at seeing a value.
- //
- if (cmdarg->syntax() & CmdArg::isVALREQ) {
- if (! (cmd_flags & QUIET)) {
- error() << "value required in same argument for "
- << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
- : KeywordPrefix(plus))
- << cmdarg->keyword_name() << " option." << endl;
- }
- rc |= (VAL_MISSING | VAL_NOTSTICKY) ;
- cmdarg->flags(save_flags);
- } else {
- // The value is optional - set the GIVEN flag and call
- // handle_arg with NULL (and check the result).
- //
- const char * null_str = NULL;
- cmdarg->set(CmdArg::GIVEN) ;
- cmd_parse_state = cmd_START_STATE ;
- bad_val = handle_arg(cmdarg, null_str);
- if (bad_val) {
- if (! (cmd_flags & QUIET)) {
- arg_error("bad value for", cmdarg) << "." << endl ;
- }
- rc |= BAD_VALUE ;
- cmdarg->flags(save_flags);
- }
- }
- } else {
- // Wait for the value to show up next time around
- cmdarg->set(CmdArg::GIVEN) ;
- cmd_matched_arg = cmdarg ;
- cmd_parse_state = cmd_WANT_VAL ;
- if (cmdarg->syntax() & CmdArg::isVALREQ) {
- cmd_parse_state += cmd_TOK_REQUIRED ;
- }
- }
- return rc ;
- }
-
- // If this option is an isVALSEP and "val" is not-NULL then we
- // have an error.
- //
- if (val && (cmdarg->syntax() & CmdArg::isVALTAKEN) &&
- (cmdarg->syntax() & CmdArg::isVALSEP)) {
- if (! (cmd_flags & QUIET)) {
- error() << "value required in separate argument for "
- << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
- : KeywordPrefix(plus))
- << cmdarg->keyword_name() << " option." << endl;
- }
- rc |= (VAL_MISSING | VAL_NOTSEP) ;
- cmdarg->flags(save_flags);
- return rc;
- }
- // handle the keyword
- bad_val = handle_arg(cmdarg, val);
- if (bad_val) {
- if (! (cmd_flags & QUIET)) {
- arg_error("bad value for", cmdarg) << "." << endl ;
- }
- rc |= BAD_VALUE ;
- cmdarg->flags(save_flags);
- }
-
- return rc ;
- }
-
-
- //-------
- // ^FUNCTION: CmdLine::parse_value - parse a Unix value
- //
- // ^SYNOPSIS:
- // unsigned CmdLine::parse_value(arg);
- //
- // ^PARAMETERS:
- // const char * arg;
- // -- the command-line argument containing the prospective value
- //
- // ^DESCRIPTION:
- // This routine will attempt to "handle" the value specified in
- // the string "arg". The compile-function of the corresponding
- // argument-value is called and the corresponding state of both
- // the command and of the matched option(s) is (are) updated.
- // If the value corresponds to a multi-valued argument, then that
- // is handled here.
- //
- // ^REQUIREMENTS:
- //
- // ^SIDE-EFFECTS:
- // "cmd" is modified accordingly for the value that is parsed (as are its
- // constituent arguments). If there are syntax errors then error messages
- // are printed if QUIET is NOT set.
- //
- // ^RETURN-VALUE:
- // NO_ERROR is returned if no errors were encountered. Otherwise the
- // return value is a combination of bitmasks of type CmdLine::CmdStatus
- // (defined in <cmdline.h>) indicating all the problems that occurred.
- //
- // ^ALGORITHM:
- // If the command-state says we are waiting for the value of an option
- // find the option that we matched last
- // else
- // match the next positional parameter in "cmd"
- // if there isnt one issue a "too many args" message
- // (unless cmd_QUIETs is set) and return.
- // endif
- // handle the given value and update the argument and command states.
- //-^^----
- unsigned
- CmdLine::parse_value(const char * arg)
- {
- unsigned save_flags = 0, rc = 0 ;
- int bad_val;
- CmdArg * cmdarg = NULL;
-
- if (cmd_parse_state & cmd_WANT_VAL) {
- if (cmd_matched_arg == NULL) {
- cerr << "*** Internal error in class CmdLine.\n"
- << "\tparse-state is inconsistent with last-matched-arg."
- << endl ;
- ::exit(e_INTERNAL);
- }
- // get back the cmdarg that we saved for later
- // - here is the value it was expecting
- //
- cmdarg = cmd_matched_arg ;
- save_flags = cmdarg->flags() ;
- } else {
- // argument is positional - find out which one it is
- cmdarg = pos_match() ;
- if (cmdarg == NULL) {
- if (! (cmd_flags & QUIET)) {
- error() << "too many arguments given." << endl ;
- }
- rc |= TOO_MANY_ARGS ;
- return rc ;
- }
- save_flags = cmdarg->flags() ;
- cmdarg->clear();
- cmdarg->set(CmdArg::POSITIONAL) ;
- if (cmd_flags & OPTS_FIRST) {
- cmd_state |= cmd_END_OF_OPTIONS ;
- }
- }
-
- // handle this value
- cmdarg->set(CmdArg::VALSEP) ;
- bad_val = handle_arg(cmdarg, arg);
- if (bad_val) {
- if (! (cmd_flags & QUIET)) {
- arg_error("bad value for", cmdarg) << "." << endl ;
- }
- rc |= BAD_VALUE ;
- cmdarg->flags(save_flags);
- if (! (cmdarg->syntax() & CmdArg::isLIST)) {
- cmd_parse_state = cmd_START_STATE;
- }
- }
-
- // If the value was okay and we were requiring a value, then
- // a value is no longer required.
- //
- if ((! bad_val) && (cmdarg->syntax() & CmdArg::isLIST)) {
- cmd_parse_state &= ~cmd_TOK_REQUIRED ;
- }
-
- return rc ;
- }
-
-
- //-------
- // ^FUNCTION: CmdLine::parse_arg - parse an argv[] element unix-style
- //
- // ^SYNOPSIS:
- // unsigned CmdLine::parse_arg(arg)
- //
- // ^PARAMETERS:
- // const char * arg;
- // -- an argument string (argv[] element) from the command-line
- //
- // ^DESCRIPTION:
- // This routine will determine whether "arg" is an option, a long-option,
- // or a value and call the appropriate parse_xxxx function defined above.
- //
- // ^REQUIREMENTS:
- //
- // ^SIDE-EFFECTS:
- // "cmd" is modified accordingly for the string that is parsed (as are its
- // constituent arguments). If there are syntax errors then error messages
- // are printed if QUIET is NOT set.
- //
- // ^RETURN-VALUE:
- // NO_ERROR is returned if no errors were encountered. Otherwise the
- // return value is a combination of bitmasks of type CmdLine::CmdStatus
- // (defined in <cmdline.h>) indicating all the problems that occurred.
- //
- // ^ALGORITHM:
- // if we are expecting a required value
- // call parse_value()
- // else if "arg" is an option
- // skip past the option prefix
- // call parse_option()
- // else if "arg" is a keyword
- // skip past the kewyord prefix
- // call parse_keyword()
- // else if "arg" is "--" (meaning end of options)
- // see that we didnt leave an option dangling without a value
- // indicate end-of-options in the command-state
- // else
- // call parse_value()
- // endif
- //-^^----
- unsigned
- CmdLine::parse_arg(const char * arg)
- {
- if (arg == NULL) return cmd_status ;
-
- int plus = (cmd_flags & ALLOW_PLUS) ; // Can we use "+"?
-
- if (cmd_parse_state & cmd_TOK_REQUIRED) {
- // If a required value is expected, then this argument MUST be
- // the value (even if it looks like an option
- //
- cmd_status |= parse_value(arg) ;
- } else if (isOPTION(arg) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
- ++arg ; // skip '-' option character
- if (cmd_flags & KWDS_ONLY) {
- cmd_state |= cmd_KEYWORDS_USED ;
- cmd_status |= parse_keyword(arg) ;
- } else {
- cmd_state |= cmd_OPTIONS_USED ;
- cmd_status |= parse_option(arg) ;
- }
- } else if ((! (cmd_flags & OPTS_ONLY))
- && isKEYWORD(arg, plus) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
- cmd_state |= cmd_KEYWORDS_USED ;
- if (*arg == '+') {
- ++arg ; // skip over '+' keyword prefix
- } else {
- arg += 2 ; // skip over '--' keyword prefix
- }
- cmd_status |= parse_keyword(arg) ;
- } else if (isENDOPTIONS(arg) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
- cmd_state |= cmd_END_OF_OPTIONS ;
- // see if we left an argument dangling without a value
- ck_need_val() ;
- } else {
- cmd_status |= parse_value(arg) ;
- }
-
- return cmd_status ;
- }
-
- //-------
- // ^FUNCTION: CmdLine::arg_error - format an argument for error messages
- //
- // ^SYNOPSIS:
- // ostream & arg_error(error_str, cmdarg);
- //
- // ^PARAMETERS:
- // const char * error_str;
- // -- the problem with the argument
- //
- // const CmdArg * cmdarg;
- // -- the argument to be formatted
- //
- // ^DESCRIPTION:
- // This function will write to "os" the argument corresponding to
- // "cmdarg" as we would like it to appear in error messages that pertain
- // to this argument.
- //
- // ^REQUIREMENTS:
- // None.
- //
- // ^SIDE-EFFECTS:
- // writes to "os"
- //
- // ^RETURN-VALUE:
- // A reference to os.
- //
- // ^ALGORITHM:
- // Pretty straightforward, just print to os the way we
- // want the argument to appear in usage messages.
- //-^^----
- ostream &
- CmdLine::arg_error(const char * error_str, const CmdArg * cmdarg) const
- {
- int plus = (cmd_flags & ALLOW_PLUS) ; // Can we use "+"?
-
- ostream & os = error() << error_str << char(' ') ;
-
- if (cmdarg->flags() & CmdArg::GIVEN) {
- if (cmdarg->flags() & CmdArg::KEYWORD) {
- os << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
- : KeywordPrefix(plus))
- << cmdarg->keyword_name() << " option" ;
- } else if (cmdarg->flags() & CmdArg::OPTION) {
- os << OptionPrefix() << (char)cmdarg->char_name() << " option" ;
- } else {
- os << cmdarg->value_name() << " argument" ;
- }
- } else {
- if (cmdarg->syntax() & CmdArg::isPOS) {
- os << cmdarg->value_name() << " argument" ;
- } else {
- if (cmd_flags & KWDS_ONLY) {
- os << OptionPrefix() << cmdarg->keyword_name() << " option" ;
- } else {
- os << OptionPrefix() << (char)cmdarg->char_name() << " option" ;
- }
- }
- }
- return os;
- }
-
-
- //-------
- // ^FUNCTION: CmdLine::fmt_arg - format an argument for usage messages
- //
- // ^SYNOPSIS:
- // unsigned CmdLine::fmt_arg(cmdarg, buf, bufsize, syntax, level);
- //
- // ^PARAMETERS:
- // const CmdArg * cmdarg;
- // -- the argument to be formatted
- //
- // char * buf;
- // -- where to print the formatted result
- //
- // unsigned bufsize;
- // -- number of bytes allocated for buf.
- //
- // CmdLine::CmdLineSyntax syntax;
- // -- the syntax to use (option, long-option, or both).
- //
- // CmdLine::CmdUsageLevel;
- // -- the usage-level corresponding to this portion of the
- // usage message.
- //
- // ^DESCRIPTION:
- // This function will write into "buf" the argument corresponding to
- // "cmdarg" as we would like it to appear in usage messages.
- //
- // ^REQUIREMENTS:
- // "buf" must be large enough to hold the result.
- //
- // ^SIDE-EFFECTS:
- // writes to "buf"
- //
- // ^RETURN-VALUE:
- // the length of the formatted result.
- //
- // ^ALGORITHM:
- // Its kind of tedious so follow along.
- //-^^----
- unsigned
- CmdLine::fmt_arg(const CmdArg * cmdarg,
- char * buf,
- unsigned bufsize,
- CmdLine::CmdLineSyntax syntax,
- CmdLine::CmdUsageLevel level) const
- {
- ostrstream oss(buf, bufsize);
- *buf = '\0';
-
- int plus = (cmd_flags & ALLOW_PLUS) ; // Can we use "+"?
- char optchar = cmdarg->char_name();
- const char * keyword = cmdarg->keyword_name();
-
- // Need to adjust the syntax if optchar or keyword is empty
- if ((! (cmdarg->syntax() & CmdArg::isPOS)) &&
- ((! optchar) || (keyword == NULL))) {
- if (keyword == NULL) {
- if ((cmd_flags & KWDS_ONLY) && (cmd_flags & NO_GUESSING)) {
- return 0;
- } else {
- syntax = cmd_OPTS_ONLY;
- }
- }
- if (! optchar) {
- if ((cmd_flags & OPTS_ONLY) && (cmd_flags & NO_GUESSING)) {
- return 0;
- } else {
- syntax = cmd_KWDS_ONLY;
- }
- }
- }
-
- // If the argument is optional - print the leading '['
- if ((level == VERBOSE_USAGE) && (! (cmdarg->syntax() & CmdArg::isREQ))) {
- oss << char('[') ;
- }
-
- // If we have a sticky-argument and usage is cmd_BOTH then it gets
- // really hairy so we just treat this as a special case right here
- // and now.
- //
- if ((syntax == cmd_BOTH) &&
- (! (cmdarg->syntax() & CmdArg::isPOS)) &&
- (cmdarg->syntax() & CmdArg::isVALTAKEN) &&
- (cmdarg->syntax() & CmdArg::isVALSTICKY))
- {
- if (cmdarg->syntax() & CmdArg::isVALOPT) {
- oss << OptionPrefix() << char(optchar) << char('[')
- << cmdarg->value_name() << "]|" << KeywordPrefix(plus)
- << keyword << "[=" << cmdarg->value_name() << char(']') ;
- } else {
- oss << OptionPrefix() << optchar << cmdarg->value_name()
- << char('|') << KeywordPrefix(plus) << keyword << char('=')
- << cmdarg->value_name() ;
- }
- if ((level == VERBOSE_USAGE) && (cmdarg->syntax() & CmdArg::isLIST)) {
- oss << " ..." ;
- }
- if ((level == VERBOSE_USAGE) && (! (cmdarg->syntax() & CmdArg::isREQ))) {
- oss << char(']') ;
- }
- oss << ends ;
- return (oss.pcount() - 1);
- }
-
- if (! (cmdarg->syntax() & CmdArg::isPOS)) {
- switch(syntax) {
- case cmd_OPTS_ONLY :
- oss << OptionPrefix() << char(optchar) ;
- break ;
-
- case cmd_KWDS_ONLY :
- oss << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
- : KeywordPrefix(plus)) << keyword ;
- break ;
-
- case cmd_BOTH :
- oss << OptionPrefix() << char(optchar) << char('|')
- << KeywordPrefix(plus) << keyword ;
- break ;
-
- default :
- cerr << "*** Internal error in class CmdLine.\n"
- << "\tunknown CmdLineSyntax value (" << int(syntax) << ")."
- << endl ;
- ::exit(e_INTERNAL);
- } //switch
- if (cmdarg->syntax() & CmdArg::isVALTAKEN) {
- if (! (cmdarg->syntax() & CmdArg::isVALSTICKY)) {
- oss << char(' ') ;
- }
- }
- }
-
- // If the argument takes a value then print the value
- if (cmdarg->syntax() & CmdArg::isVALTAKEN) {
- if ((! (cmdarg->syntax() & CmdArg::isPOS)) &&
- (cmdarg->syntax() & CmdArg::isVALOPT))
- {
- oss << char('[') ;
- }
- if (cmdarg->syntax() & CmdArg::isVALSTICKY) {
- if (syntax == cmd_KWDS_ONLY) oss << char('=') ;
- }
- oss << cmdarg->value_name() ;
- if ((level == VERBOSE_USAGE) && (cmdarg->syntax() & CmdArg::isLIST)) {
- oss << " ..." ;
- }
- if ((! (cmdarg->syntax() & CmdArg::isPOS)) &&
- (cmdarg->syntax() & CmdArg::isVALOPT))
- {
- oss << char(']') ;
- }
- }
-
- if ((level == VERBOSE_USAGE) && (! (cmdarg->syntax() & CmdArg::isREQ))) {
- oss << char(']') ;
- }
- oss << ends ;
-
- return (oss.pcount() - 1) ;
- }
-
-